﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace urBook.Engine.VcfUtilities
{
    /// <summary>
    /// Class VcfManager is a static class that provides the Address Book the ability to import/export vCard format
    /// </summary>
    public static class VcfManager
    {
        /// <summary>
        /// Imports vCard format contacts to a new Address Book.
        /// <param name="path">File system path to the vCard file</param>
        /// <returns>Address Book for imported contacts</returns>
        /// </summary>
        public static AddressBook import(string path)
        {
            AddressBook addressBook = new AddressBook();

            if (!File.Exists(path))
                throw new FileNotFoundException();

            using (StreamReader sr = File.OpenText(path))
            {
                string s = "";
                while ((s = sr.ReadLine()) != null)
                    if (s.StartsWith("BEGIN:VCARD"))
                    {
                        ContactCard c = new ContactCard();
                        while ((s = sr.ReadLine()) != "END:VCARD")
                        {
                            #region Name
                            if (s.StartsWith("N:"))
                            {
                                try
                                {

                                    string[] splits = s.Split(new char[] { ':', ';' });
                                    Name contactName = new Name();
                                    contactName.firstName = splits[2];
                                    contactName.lastName = splits[1];
                                    c.name = contactName;
                                }
                                catch (Exception a) { }
                            }
                            #endregion
                            #region Organization
                            else if (s.StartsWith("ORG:"))
                                c.company = s.Substring(4);
                            #endregion
                            #region Title
                            else if (s.StartsWith("TITLE:"))
                                c.title = s.Substring(6);
                            #endregion
                            #region Photo
                            else if (s.StartsWith("PHOTO"))
                            {
                                try
                                {
                                    Photo p;
                                    if (s.Contains("URL"))
                                    {
                                        p = new Photo();
                                        string[] splits = s.Split(new char[] { ';', ':' }, 4);
                                        p.ext = splits[2].Substring(5);
                                        p.url = splits[3];
                                    }
                                    else
                                    {
                                        p = new EmbeddedPhoto();
                                        EmbeddedPhoto ep = (EmbeddedPhoto)p;
                                        string[] splits = s.Split(new char[] { ';', ':' }, 4);
                                        ep.ext = splits[1].Substring(5);
                                        ep.encoding = splits[2].Substring(9);
                                        string content = "";
                                        while ((content = sr.ReadLine()) != "")
                                            ep.imageBuffer += content;
                                        ep.imageBuffer = ep.imageBuffer.Replace(" ", "");
                                        ep.imageBuffer = ep.imageBuffer.Replace("\n", "");
                                        ep.imageBuffer = ep.imageBuffer.Replace("\r", "");
                                        s = content;
                                    }
                                    c.photo = p;
                                }
                                catch (Exception a) { }
                            }
                            #endregion
                            #region Telephone
                            else if (s.StartsWith("TEL"))
                            {
                                Telephone t = new Telephone();

                                if (s.Contains("HOME"))
                                    t.type = Type.HOME;
                                else if (s.Contains("WORK"))
                                    t.type = Type.WORK;
                                else if (s.Contains("FAX"))
                                    t.type = Type.FAX;
                                else if (s.Contains("CELL"))
                                    t.type = Type.CELL;
                                else
                                    t.type = Type.OTHER;

                                if (s.Contains("PREF"))
                                    t.isPreferred = true;

                                string[] splits = s.Split(new char[] { ';', ':' });
                                t.value = splits.Last();
                                c.phones.Add(t);
                            }
                            #endregion
                            #region Address
                            else if (s.StartsWith("ADR"))
                            {
                                try
                                {
                                    Address a = new Address();

                                    string[] splits = s.Split(new char[] { ';', ':' });
                                    a.country = splits.Last();
                                    a.postalCode = splits[splits.Length - 2];
                                    a.state = splits[splits.Length - 3];
                                    a.city = splits[splits.Length - 4];
                                    a.street = splits[splits.Length - 5];

                                    if (s.Contains("WORK"))
                                    {
                                        a.type = Type.WORK;
                                        c.workAddress = a;
                                    }
                                    else
                                    {
                                        a.type = Type.HOME;
                                        c.homeAddress = a;
                                    }
                                }
                                catch (Exception a) { }
                            }
                            #endregion
                            #region Email
                            else if (s.StartsWith("EMAIL"))
                            {
                                Email e = new Email();

                                string[] splits = s.Split(new char[] { ';', ':' });
                                e.type = (s.Contains("HOME") ? e.type = Type.HOME :
                                    s.Contains("WORK") ? e.type = Type.WORK :
                                    e.type = Type.OTHER);
                                e.value = splits.Last();
                                e.value = e.value.Replace("=40", "@");

                                if (s.Contains("PREF"))
                                    e.isPreferred = true;

                                c.emails.Add(e);
                            }
                            #endregion
                            #region URL
                            else if (s.StartsWith("URL"))
                                c.url = s.Split(new char[] { ';', ':' }, 2).Last();
                            #endregion
                            #region Group
                            else if (s.StartsWith("X-CATEGORIES"))
                            {
                                string[] splits = s.Split(new char[] { ';', ':' });
                                for (int i = 1; i < splits.Length; i++)
                                {
                                    if (splits[i] != "")
                                    {
                                        c.groups.Add(splits[i]);
                                        Utilities.getGroupByName(addressBook, splits[i]).contacts.Add(c);
                                    }
                                }
                            }
                            #endregion
                            #region Notes
                            else if (s.StartsWith("X-"))
                                c.notes += s + "\n";
                            #endregion
                        }
                        addressBook.contacts.Add(c);
                    }
                return addressBook;
            }
        }

        /// <summary>
        /// Exports Address Book contacts to vCard format.
        /// <param name="path">File system path to the vCard file</param>
        /// <param name="ab">Address Book for contacts to export</returns>
        /// </summary>
        public static void export(AddressBook ab, string path)
        {
            StreamWriter sw = new StreamWriter(path);
            sw.WriteLine(ab.toVcfString());
            sw.Close();
        }
        /// <summary>
        /// Exports Contact card to vCard format.
        /// <param name="path">File system path to the vCard file</param>
        /// <param name="cc">Contact card to export</returns>
        /// </summary>
        public static void export(ContactCard cc, string path)
        {
            StreamWriter sw = new StreamWriter(path);
            sw.WriteLine(cc.toVcfString());
            sw.Close();
        }
    }
}
